Skip to content

fix(accounts): store Dunning overdue outstanding in transaction currency#1

Open
devansh19299 wants to merge 2 commits into
developfrom
fix/dunning-outstanding-transaction-currency
Open

fix(accounts): store Dunning overdue outstanding in transaction currency#1
devansh19299 wants to merge 2 commits into
developfrom
fix/dunning-outstanding-transaction-currency

Conversation

@devansh19299

@devansh19299 devansh19299 commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Refs frappe#56006

Fix: Incorrect Dunning Outstanding Amount for Foreign-Currency Invoices

The Problem

When a Dunning is created from a foreign-currency Sales Invoice whose receivable (debit_to) account is in the company currency (i.e., party_account_currency != currency), the overdue payment outstanding displays both the wrong value and the wrong currency label.

Example:
An invoice is booked for 24,530.36 USD against a EUR company receivable account (equivalent to 20,907.15 EUR).

  • The Bug: The dunning (currency USD) displays 20,907.15 US$. It incorrectly paints the EUR company-currency amount with a USD label.
  • The Expected Result: The correct outstanding amount should be 24,530.36 USD.

Root Cause

In create_dunningpostprocess_dunning (located in erpnext/accounts/doctype/sales_invoice/mapper.py), the mapped Overdue Payment.outstanding for a single payment-schedule row was being overwritten with Sales Invoice.outstanding_amount.

Because outstanding_amount is tracked in the party account currency—which in this scenario is the company currency—a company-currency figure was forced into a transaction-currency field. This incorrect value then propagated into total_outstanding and grand_total.

Note: This behavior was introduced by frappe#41817 (commits 04f0c96af7, b7c3fa23d2) to reflect the live invoice outstanding. While the intent was valid, the currency distinction was missed. The bug remained hidden in existing tests because they only covered the common case where party_account_currency == currency.


The Fix

The fix introduces conditional logic to handle mixed currencies properly:

  • Foreign Currency (party_account_currency != currency): Use Payment Schedule.outstanding instead of outstanding_amount. This field is already in the transaction currency and is kept current with payments.
  • Same Currency (party_account_currency == currency): Continue using outstanding_amount to preserve the intended behavior of fix: use invoice outstanding on Dunning frappe/erpnext#41817.

Test Coverage

The following tests have been added to test_dunning.py to ensure stability and prevent regressions:

  • test_dunning_outstanding_in_transaction_currency: Tests a foreign-currency invoice against a company-currency receivable. Asserts the dunning row carries the transaction-currency amount, not the outstanding_amount. (Note: This test fails without this PR).
  • test_dunning_outstanding_same_currency_no_regression: Guards the logic introduced in fix: use invoice outstanding on Dunning frappe/erpnext#41817 to ensure it still functions properly for same-currency invoices.
  • test_dunning_multi_installment_foreign_currency: Ensures that multi-row payment schedules retain their correct transaction-currency values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant